using System;
using System.Collections.Generic;
using System.Text;

namespace BAFIRCSharp.Messages
{
    public class MessageBase : MarshalByRefObject
    {
        public string Command;

        virtual public string BuildMessage()
        {
            return "\r\n";
        }
    }

    public class Pass : MessageBase
    {
        public string Password;

        public Pass()
        {
            Command = "PASS";
            Password = "";
        }

        public Pass(string Password)
        {
            Command = "PASS";
            this.Password = Password;
        }

        public override string BuildMessage()
        {
            return Command + " " + Password + "\r\n";
        }
    }

    public class Nick : MessageBase
    {
        public string Nickname;

        public Nick()
        {
            Command = "NICK";
            Nickname = "";
        }

        public Nick(string Nickname)
        {
            Command = "NICK";
            this.Nickname = Nickname;
        }

        public override string BuildMessage()
        {
            return Command + " " + Nickname + "\r\n";
        }
    }

    public class User : MessageBase
    {
        public string Username;
        public string Hostname;
        public string Servername;
        public string Realname;

        public User()
        {
            Command = "USER";
            Username = "";
            Hostname = "";
            Servername = "";
            Realname = "";
        }

        public User(string Username, string Hostname, string Servername, string Realname)
        {
            Command = "USER";
            this.Username = Username;
            this.Hostname = Hostname;
            this.Servername = Servername;
            this.Realname = Realname;
        }

        public override string BuildMessage()
        {
            return Command + " " + Username + " " + Hostname + " " + Servername + " :" + Realname + "\r\n";
        }
    }

    public class Oper : MessageBase
    {
        public string Username;
        public string Password;

        public Oper()
        {
            Command = "OPER";
            Username = "";
            Password = "";
        }

        public Oper(string Username, string Password)
        {
            Command = "OPER";
            this.Username = Username;
            this.Password = Password;
        }

        public override string BuildMessage()
        {
            return Command + " " + Username + " " + Password + "\r\n";
        }
    }

    public class Quit : MessageBase
    {
        public string Message;

        public Quit()
        {
            Command = "QUIT";
            Message = "";
        }

        public Quit(string Message)
        {
            Command = "QUIT";
            this.Message = Message;
        }

        public override string BuildMessage()
        {
            return Command + " :" + Message + "\r\n";
        }
    }

    public class Join : MessageBase
    {
        public string Channel;
        public string Keyword;

        public Join()
        {
            Command = "JOIN";
            Channel = "";
            Keyword = "";
        }

        public Join(string Channel)
        {
            Command = "JOIN";
            this.Channel = Channel;
            this.Keyword = "";
        }

        public Join(string Channel, string Keyword)
        {
            Command = "JOIN";
            this.Channel = Channel;
            this.Keyword = Keyword;
        }

        public override string BuildMessage()
        {
            return Command + " " + Channel + " " + Keyword + "\r\n";
        }
    }

    public class Part : MessageBase
    {
        public string Channel;
        public string Reason;

        public Part()
        {
            Command = "PART";
            Channel = "";
            Reason = "";
        }

        public Part(string Channel)
        {
            Command = "PART";
            this.Channel = Channel;
            this.Reason = "";
        }

        public Part(string Channel, string Reason)
        {
            Command = "PART";
            this.Channel = Channel;
            this.Reason = Reason;
        }

        public override string BuildMessage()
        {
            return Command + " " + Channel + " :" + Reason + "\r\n";
        }
    }

    public class Mode : MessageBase
    {
        public string ChanNick;
        public string Modes;

        public Mode()
        {
            Command = "MODE";
            ChanNick = "";
            Modes = "";
        }

        public Mode(string ChanNick, string Modes)
        {
            Command = "MODE";
            this.ChanNick = ChanNick;
            this.Modes = Modes;
        }

        public Mode(string ChanNick, string Modes, string Params)
        {
            Command = "MODE";
            this.ChanNick = ChanNick;
            this.Modes = Modes + " " + Params;
        }

        public override string BuildMessage()
        {
            return Command + " " + ChanNick + " " + Modes + "\r\n";
        }
    }

    public class Topic : MessageBase
    {
        public string Channel;
        public string Topic_;

        public Topic()
        {
            Command = "TOPIC";
            Channel = "";
            Topic_ = "";
        }

        public Topic(string Channel)
        {
            Command = "TOPIC";
            this.Channel = Channel;
            this.Topic_ = "";
        }

        public Topic(string Channel, string Topic_)
        {
            Command = "TOPIC";
            this.Channel = Channel;
            this.Topic_ = Topic_;
        }

        public override string BuildMessage()
        {
            string Cmd = Command + " " + Channel;
            if (Topic_ != string.Empty)
                Cmd += " :" + Topic_;
            Cmd += "\r\n";
            return Cmd;
        }
    }

    public class Names : MessageBase
    {
        public string Chans;

        public Names()
        {
            Command = "NAMES";
            Chans = "";
        }

        public Names(string Chans)
        {
            Command = "NAMES";
            this.Chans = Chans;
        }

        public override string BuildMessage()
        {
            return Command + " " + Chans + "\r\n";
        }
    }

    public class List : MessageBase
    {
        public string Chans;

        public List()
        {
            Command = "LIST";
            Chans = "";
        }

        public List(string Chans)
        {
            Command = "LIST";
            this.Chans = Chans;
        }

        public override string BuildMessage()
        {
            return Command + " " + Chans + "\r\n";
        }
    }

    public class Invite : MessageBase
    {
        public string Nickname;
        public string Channel;

        public Invite()
        {
            Command = "INVITE";
            Nickname = "";
            Channel = "";
        }

        public Invite(string Nickname, string Channel)
        {
            Command = "INVITE";
            this.Nickname = Nickname;
            this.Channel = Channel;
        }

        public override string BuildMessage()
        {
            return Command + " " + Nickname + " " + Channel + "\r\n";
        }
    }

    public class Kick : MessageBase
    {
        public string Channel;
        public string Nickname;
        public string Reason;

        public Kick()
        {
            Command = "KICK";
            Channel = "";
            Nickname = "";
            Reason = "";
        }

        public Kick(string Channel, string Nickname)
        {
            Command = "KICK";
            this.Channel = Channel;
            this.Nickname = Nickname;
            this.Reason = "";
        }

        public Kick(string Channel, string Nickname, string Reason)
        {
            Command = "KICK";
            this.Channel = Channel;
            this.Nickname = Nickname;
            this.Reason = Reason;
        }

        public override string BuildMessage()
        {
            string Cmd = Command + " " + Channel + " " + Nickname;
            if (Reason != string.Empty)
                Cmd += " :" + Reason;
            Cmd += "\r\n";
            return Cmd;
        }
    }

    public class Version : MessageBase
    {
        public string Server;

        public Version()
        {
            Command = "VERSION";
            Server = "";
        }

        public Version(string Server)
        {
            Command = "VERSION";
            this.Server = Server;
        }

        public override string BuildMessage()
        {
            return Command + " " + Server + "\r\n";
        }
    }

    public class Stats : MessageBase
    {
        public string Query;
        public string Server;

        public Stats()
        {
            Command = "STATS";
            Query = "";
            Server = "";
        }

        public Stats(string Query)
        {
            Command = "STATS";
            this.Query = Query;
            this.Server = "";
        }

        public Stats(string Query, string Server)
        {
            Command = "STATS";
            this.Query = Query;
            this.Server = Server;
        }

        public override string BuildMessage()
        {
            return Command + " " + Query + " " + Server + "\r\n";
        }
    }

    public class Links : MessageBase
    {
        public string RemoteServer;
        public string ServerMask;

        public Links()
        {
            Command = "LINKS";
            RemoteServer = "";
            ServerMask = "";
        }

        public Links(string RemoteServer)
        {
            Command = "LINKS";
            this.RemoteServer = RemoteServer;
            this.ServerMask = "";
        }

        public Links(string RemoteServer, string ServerMask)
        {
            Command = "LINKS";
            this.RemoteServer = RemoteServer;
            this.ServerMask = ServerMask;
        }

        public override string BuildMessage()
        {
            return Command + " " + RemoteServer + " " + ServerMask + "\r\n";
        }
    }

    public class Time : MessageBase
    {
        public string Server;

        public Time()
        {
            Command = "TIME";
            Server = "";
        }

        public Time(string Server)
        {
            Command = "TIME";
            this.Server = Server;
        }

        public override string BuildMessage()
        {
            return Command + " " + Server + "\r\n";
        }
    }

    public class Connect : MessageBase
    {
        public string TargetServer;
        public int Port;
        public string RemoteServer;

        public Connect()
        {
            Command = "CONNECT";
            TargetServer = "";
            Port = 0;
            RemoteServer = "";
        }

        public Connect(string TargetServer)
        {
            Command = "CONNECT";
            this.TargetServer = TargetServer;
            this.Port = 0;
            this.RemoteServer = "";
        }

        public Connect(string TargetServer, int Port)
        {
            Command = "CONNECT";
            this.TargetServer = TargetServer;
            this.Port = Port;
            this.RemoteServer = "";
        }

        public Connect(string TargetServer, int Port, string RemoteServer)
        {
            Command = "CONNECT";
            this.TargetServer = TargetServer;
            this.Port = Port;
            this.RemoteServer = RemoteServer;
        }

        public override string BuildMessage()
        {
            return Command + " " + TargetServer + " " + Port + " " + RemoteServer + "\r\n";
        }
    }

    public class Trace : MessageBase
    {
        public string Server;

        public Trace()
        {
            Command = "TRACE";
            Server = "";
        }

        public Trace(string Server)
        {
            Command = "TRACE";
            this.Server = Server;
        }

        public override string BuildMessage()
        {
            return Command + " " + Server + "\r\n";
        }
    }

    public class Admin : MessageBase
    {
        public string Server;

        public Admin()
        {
            Command = "ADMIN";
            Server = "";
        }

        public Admin(string Server)
        {
            Command = "ADMIN";
            this.Server = Server;
        }

        public override string BuildMessage()
        {
            return Command + " " + Server + "\r\n";
        }
    }

    public class Info : MessageBase
    {
        public string Server;

        public Info()
        {
            Command = "INFO";
            Server = "";
        }

        public Info(string Server)
        {
            Command = "INFO";
            this.Server = Server;
        }

        public override string BuildMessage()
        {
            return Command + " " + Server + "\r\n";
        }
    }

    public class PrivMsg : MessageBase
    {
        public string Destination;
        public string Message;

        public PrivMsg()
        {
            Command = "PRIVMSG";
            Destination = "";
            Message = "";
        }

        public PrivMsg(string Destination, string Message)
        {
            Command = "PRIVMSG";
            this.Destination = Destination;
            this.Message = Message;
        }

        public override string BuildMessage()
        {
            return Command + " " + Destination + " :" + Message + "\r\n";
        }
    }

    public class Notice : MessageBase
    {
        public string Destination;
        public string Message;

        public Notice()
        {
            Command = "NOTICE";
            Destination = "";
            Message = "";
        }

        public Notice(string Destination, string Message)
        {
            Command = "NOTICE";
            this.Destination = Destination;
            this.Message = Message;
        }

        public override string BuildMessage()
        {
            return Command + " " + Destination + " :" + Message + "\r\n";
        }
    }

    public class Who : MessageBase
    {
        public string Name;
        public bool O;

        public Who()
        {
            Command = "WHO";
            Name = "";
            O = false;
        }

        public Who(string Name)
        {
            Command = "WHO";
            this.Name = Name;
            this.O = false;
        }

        public Who(string Name, bool O)
        {
            Command = "WHO";
            this.Name = Name;
            this.O = O;
        }

        public override string BuildMessage()
        {
            string Cmd = Command + "" + Name;
            if (O)
                Cmd += " O";
            Cmd += "\r\n";
            return Cmd;
        }
    }

    public class Whois : MessageBase
    {
        public string Server;
        public string Nickmask;

        public Whois()
        {
            Command = "WHOIS";
            Server = "";
            Nickmask = "";
        }

        public Whois(string Server)
        {
            Command = "WHOIS";
            this.Server = Server;
            this.Nickmask = "";
        }

        public Whois(string Server, string Nickmask)
        {
            Command = "WHOIS";
            this.Server = Server;
            this.Nickmask = Nickmask;
        }

        public override string BuildMessage()
        {
            string Cmd = Command + " ";
            if (Server != string.Empty)
                Cmd += Server + " ";
            Cmd += Nickmask + "\r\n";
            return Cmd;
        }
    }

    public class Whowas : MessageBase
    {
        public string Nickname;
        public int Count;
        public string Server;

        public Whowas()
        {
            Command = "WHOWAS";
            Nickname = "";
            Count = 0;
            Server = "";
        }

        public Whowas(string Nickname)
        {
            Command = "WHOWAS";
            this.Nickname = Nickname;
            this.Count = 0;
            this.Server = "";
        }

        public Whowas(string Nickname, int Count)
        {
            Command = "WHOWAS";
            this.Nickname = Nickname;
            this.Count = Count;
            this.Server = "";
        }

        public Whowas(string Nickname, int Count, string Server)
        {
            Command = "WHOWAS";
            this.Nickname = Nickname;
            this.Count = Count;
            this.Server = Server;
        }

        public override string BuildMessage()
        {
            return Command + " " + Nickname + " " + Count + " " + Server + "\r\n";
        }
    }

    public class Kill : MessageBase
    {
        public string Nickname;
        public string Comment;

        public Kill()
        {
            Command = "KILL";
            Nickname = "";
            Comment = "";
        }

        public Kill(string Nickname, string Comment)
        {
            Command = "KILL";
            this.Nickname = Nickname;
            this.Comment = Comment;
        }

        public override string BuildMessage()
        {
            return Command + " " + Nickname + " " + Comment + "\r\n";
        }
    }

    public class Ping : MessageBase
    {
        public string Server1;
        public string Server2;

        public Ping()
        {
            Command = "PING";
            Server1 = "";
            Server2 = "";
        }

        public Ping(string Server1)
        {
            Command = "PING";
            this.Server1 = Server1;
            this.Server2 = "";
        }

        public Ping(string Server1, string Server2)
        {
            Command = "PING";
            this.Server1 = Server1;
            this.Server2 = Server2;
        }

        public override string BuildMessage()
        {
            return Command + " " + Server1 + " " + Server2 + "\r\n";
        }
    }

    public class Pong : MessageBase
    {
        public string Daemon1;
        public string Daemon2;

        public Pong()
        {
            Command = "PONG";
            Daemon1 = "";
            Daemon2 = "";
        }

        public Pong(string Daemon1)
        {
            Command = "PONG";
            this.Daemon1 = Daemon1;
            this.Daemon2 = "";
        }

        public Pong(string Daemon1, string Daemon2)
        {
            Command = "PONG";
            this.Daemon1 = Daemon1;
            this.Daemon2 = Daemon2;
        }

        public override string BuildMessage()
        {
            return Command + " " + Daemon1 + " " + Daemon2 + "\r\n";
        }
    }

    public class CTCPQuery : MessageBase
    {
        public string Destination;
        public string CTCP;
        public string Params;

        public CTCPQuery()
        {
            Command = "PRIVMSG";
            Destination = "";
            CTCP = "";
            Params = "";
        }

        public CTCPQuery(string Destination, string CTCP)
        {
            Command = "PRIVMSG";
            this.Destination = Destination;
            this.CTCP = CTCP;
            this.Params = "";
        }

        public CTCPQuery(string Destination, string CTCP, string Params)
        {
            Command = "PRIVMSG";
            this.Destination = Destination;
            this.CTCP = CTCP;
            this.Params = Params;
        }

        public override string BuildMessage()
        {
            return (new PrivMsg(Destination, '\x01' + CTCP + " " + Params + '\x01')).BuildMessage();
        }
    }

    public class CTCPReply : MessageBase
    {
        public string Destination;
        public string CTCP;
        public string Params;

        public CTCPReply()
        {
            Command = "NOTICE";
            Destination = "";
            CTCP = "";
            Params = "";
        }

        public CTCPReply(string Destination, string CTCP)
        {
            Command = "NOTICE";
            this.Destination = Destination;
            this.CTCP = CTCP;
            this.Params = "";
        }

        public CTCPReply(string Destination, string CTCP, string Params)
        {
            Command = "NOTICE";
            this.Destination = Destination;
            this.CTCP = CTCP;
            this.Params = Params;
        }

        public override string BuildMessage()
        {
            return (new Notice(Destination, '\x01' + CTCP + " " + Params + '\x01')).BuildMessage();
        }
    }
}
